#include "queue.h"

/**
 *  功  能：
 *      创建一个队列
 *  参  数：
 *      无
 *  返回值：
 *      成功：创建完成的队列
 *      失败：NULL
 **/
pQueue *create_PQueue()
{
    pQueue *queue = (pQueue *)malloc(sizeof(pQueue));
    if (queue != NULL)
    {
        queue->node = NULL;
        queue->count = 0;
    }

    return queue;
}

/**
 *  功  能：
 *      队列中插入节点元素
 *  参  数：
 *      queue   ：要操作的队列句柄
 *      node    ：插入的节点元素
 *      priority：节点出现的次数，优先级
 *  返回值：
 *      0 ： 成功
 *     -1 ：操作异常
 *     -2 ：参数异常
 *     -3 ：队列满
 **/
int push_PQueue(pQueue **queue, queueNode *node, unsigned int priority)
{
    int ret = 0;

    if (queue == NULL || *queue == NULL || node == NULL)
    {
        ret = -2;
        goto ERROR_END;
    }
    if ((*queue)->count == MAX_SZ)
    {
        ret = -3;
        goto ERROR_END;
    }
    //创建一个队列节点
    pQueueNode *tmpNode = (pQueueNode *)malloc(sizeof(pQueueNode));
    if (tmpNode == NULL)
    {
        ret = -1;
        goto ERROR_END;
    }
    tmpNode->priority = priority;
    tmpNode->qnode = node;

    // 如果是一个空队列，直接进行插入的操作
    if ((*queue)->count == 0 || (*queue)->node == NULL)
    {
        tmpNode->next = NULL;
        (*queue)->node = tmpNode;
        (*queue)->count = 1; // count等于1，因为确定是第一次加入节点，等于
        goto NORMAL_END;     // 执行完成直接结束
    }
    else // 不是空队列
    {
        // 如果优先级或者次数小于的第一个节点，那就直接插入到第一个节点上
        if (priority <= (*queue)->node->priority)
        {
            tmpNode->next = (*queue)->node; // 新节点的next指向队列中原本第一个节点
            (*queue)->node = tmpNode;       //队列中的第一个节点为新的节点
            (*queue)->count += 1;           // count加1，以为
            goto NORMAL_END;                // 执行完成直接结束
        }
        else
        {
            // 声明一个迭代器，配合while实现for的功能
            pQueueNode *iterator = (*queue)->node;

            while (iterator->next != NULL)
            {
                // 如果优先级小于当前节点的优先级，则进行插入
                if (priority <= iterator->next->priority)
                {
                    tmpNode->next = iterator->next;
                    iterator->next = tmpNode;
                    (*queue)->count++;
                    goto NORMAL_END; // 执行完成直接结束
                }
                // 指针后移
                iterator = iterator->next;
            }
            // 最后一个节点，最为尾节点插入
            if (iterator->next == NULL)
            {
                tmpNode->next = NULL;
                iterator->next = tmpNode;
                (*queue)->count++;
                goto NORMAL_END; // 执行完成直接结束
            }
        }
    }

NORMAL_END:
ERROR_END:

    return ret;
}

/**
 *  功  能：
 *      队列中获取节点元素
 *  参  数：
 *      queue ：要操作的队列句柄 
 *  返回值：
 *      成功 ：队列头接单
 *      失败 ：NULL
 **/
queueNode *pop_PQueue(pQueue **queue)
{
    queueNode *retVal = NULL;

    if (queue == NULL || *queue == NULL)
        goto END;
    // 将队列中的第一个节点暂存起来
    pQueueNode *temp = (*queue)->node;

    // 如果存在节点，队列不为空，并且当前节点存在有效额节点
    if ((*queue)->count < 0 || temp == NULL)
        goto END;

    //将队列的头节点王后面移动
    (*queue)->node = temp->next;
    //自减
    (*queue)->count--;
    // 节点的值赋值
    retVal = temp->qnode;

    // 释放掉队列中pop出来的节点 -- pQueueNode
    if (temp != NULL)
        free(temp);

END:
    return retVal;
}

/**
 *  功  能：
 *      销毁一个队列
 *  参  数：
 *      要销毁的队列
 *  返回值：
 *      无
 **/
void destory_PQueue(pQueue *queue)
{
    if ((queue) != NULL)
    {
        free(queue);
        queue = NULL;
    }
}

func_queue fqueue = {
    create_PQueue,
    push_PQueue,
    pop_PQueue,
    destory_PQueue};
